﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Data;
using MySQLDriverCS;

namespace DBServerLibrary.DB
{
    class ConnectionManager
    {
        /// <summary>
        /// //同步执行的Sql 链接类
        /// </summary>
        private MySQLConnection Conn;
        /// <summary>
        /// //同步执行的Sql 命令类
        /// </summary>
        private MySQLCommand _Comm = new MySQLCommand();
        /// <summary>
        /// 用于异步执行的SQL命令类列表
        /// </summary>
        private List<MySQLCommand> CommandList;
        /// <summary>
        /// 执行线程
        /// </summary>
        private Thread ExecuteNonQueryThread;
        /// <summary>
        /// SQL列表
        /// </summary>
        private List<string> SqlList;
        /// <summary>
        /// 执行线程的信号量
        /// </summary>
        private Semaphore _pool;

        /// <summary>
        /// 初始化数据库操作类
        /// </summary>
        /// <param name="server"></param>
        /// <param name="database"></param>
        /// <param name="login"></param>
        /// <param name="pass"></param>
        /// <param name="ConnectionCount"></param>
        public void init(string server, string database, string login, string pass,int ConnectionCount)
        {
            //执行线程的信号量
            _pool = new Semaphore(ConnectionCount, ConnectionCount);

            MySQLConnectionString ConnectionString = new MySQLConnectionString(server, database, login, pass);
            
            Conn = new MySQLConnection(ConnectionString.AsString);
            
            CommandList = new List<MySQLCommand>();
            for (int i = 0; i < ConnectionCount; i++)
            {
                MySQLConnection Connection = new MySQLConnection(ConnectionString.AsString);
                Connection.Open();
                MySQLCommand Comm = new MySQLCommand();
                Comm.Connection = Connection;
                CommandList.Add(Comm);
            }

            SqlList = new List<string>();

            ExecuteNonQueryThread = new Thread(ExecuteNonQueryThreadFunc);
            ExecuteNonQueryThread.Start();
        }

        public void Release()
        {
            ExecuteNonQueryThread.Abort();
            foreach (MySQLCommand Comm in CommandList)
            {
                Comm.Connection.Close();
            }
            Conn.Close();
        }

        /// <summary>
        /// 取得查询数据。
        /// </summary>
        /// <param name="SqlStr"></param>
        /// <returns></returns>
        public DataTable GetDataTable(string SqlStr)
        {
            MySQLDataAdapter mda = new MySQLDataAdapter(SqlStr,Conn);
            DataSet ds = new DataSet();
            mda.Fill(ds);
            return ds.Tables[0];
        }

        /// <summary>
        /// 同步方式执行SQL语句。
        /// </summary>
        /// <param name="SqlStr"></param>
        /// <returns></returns>
        public int ExecuteNonQuery(string SqlStr)
        {
            _Comm.Connection = Conn;
            _Comm.CommandText = SqlStr;
            return _Comm.ExecuteNonQuery();
        }
       /// <summary>
       /// 异步执行Sql,无返回值的Sql
       /// </summary>
       /// <param name="SqlStr"></param>
        public void AsycExecuteNonQuery(string SqlStr)
        {
            lock (SqlList)
            {
                SqlList.Add(SqlStr);
            }
        }
        /// <summary>
        /// 在线程池中执行SQL
        /// </summary>
        /// <param name="obj"></param>
        private void ThreadPoolFunction(object obj)
        {

            MySQLCommand Comm = (MySQLCommand)obj;
            try
            {
                Comm.ExecuteNonQuery();
            }
            catch (Exception ex)
            {

            }
            lock (CommandList)
            {
                CommandList.Add(Comm);
            }
            _pool.Release();
        }

        /// <summary>
        /// 异步执行Sql的线程。
        /// </summary>
        /// <param name="obj"></param>
        private void ExecuteNonQueryThreadFunc(object obj)
        {
            while(true)
            {
                _pool.WaitOne();
                string SqlStr = null;
                lock(SqlList)
                {
                    if(SqlList.Count>0)
                    {
                        SqlStr = SqlList[0];
                        SqlList.RemoveAt(0);
                    }
                }
                if (SqlStr != null)
                {
                    MySQLCommand Comm = null;
                    lock (CommandList)
                    {
                        Comm = CommandList[0];
                        CommandList.RemoveAt(0);
                    }
                    ThreadPool.QueueUserWorkItem(ThreadPoolFunction, Comm);
                }
                else
                {
                    Thread.Sleep(500);
                }
            }
        }

    }
}
